# -*- coding: utf-8 -*-
'''对系统模块os目录，文件操作的扩展'''


import os
import sys
import stat
import shutil
import cPickle
import time
import tempfile
import fnmatch

#pywin32 操作系统依赖类库
import win32file
import pywintypes


class FileData:
    def __init__(self):
        self.name=''
        self.size=-1
        self.modifyTime=-1
        self.id=''
        
    def __cmp__(self, other):
        if not isinstance(other, FileData):            
            return False
        
        return self.name is other.name\
            and self.size is other.size\
            and self.modifyTime is other.modifyTime\
            and self.id is other.id
    
def exists( path ):
    return os.path.exists( path )
    
def rmdir( path ):
    os.rmdir(path)

def makedirs( path ):
    os.makedirs( path )

def makeFileDirs(filePath):
    """
    makeFileDirs(basestring filePath)
    
    构造出一个文件路径所需的目录,文件存在与否无所谓:
    例: 
      makeFileDirs('a\b\c.txt') 
      如果目录'a\b'本身就存在,啥也不做        
      如果目录'a\b'不存在就建立'a\b'
    """
    dir=os.path.split(filePath)[0]
    if dir!='' and not os.path.exists(dir):
        os.mkdir(dir)


def createFile( filePath, fileContent='' ,modifyTime=None):
    """
       createFile(basestring filePath, basestring fileContent='' ,bool modifyTime=None)
       
       create a file
       args:
         filePath : file path
         fileContent: write to new file
         modifyTime: file modify time ,set to new file
    """
    dir=os.path.split(filePath)[0]# os.path.split return -> 0: dir 1:filename
    if dir != '' and not os.path.exists(dir) :
        os.makedirs(dir) 
    f=file( filePath, 'wb+' )

    try:
        f.write( fileContent )
        if modifyTime is not None:
            _setFileModifyTime(f,modifyTime)
    except Exception ,e:
        raise Exception,"createFile"+filePath+"\n inner exception:"+str(e)
    f.close()
    return filePath

def createTempFile(filename,fileContent):
    tempDir=os.path.join(tempfile.gettempdir(),'pystore')
    if not exists(tempDir):
        makedirs(tempDir)
    filepath=os.path.join(tempDir,filename)
    return createFile(filepath,fileContent)

def makeTempDirs():
    """ 
    createTempDir() -> str 
    
    返回一个专用的temp目录路径
    """
    tempDir=os.path.join(tempfile.gettempdir(),'pystore')
    if not os.path.exists(tempDir):
        os.makedirs( tempDir )
    return tempDir

def readFile( path ):
    f=file( path, 'r' )
    result=f.read()
    f.close()  
    return result

def removeFile( path ):
    os.remove( path )
    
def getFileModifyTime( path ):
    return __getFileStatOf ( path, stat.ST_MTIME )
    
def setFileModifyTime(path,modifyTime):
    """
       string path : file path
       int modifyTime: file modify time
    """
    f=file(path,'a+')
    _setFileModifyTime(f,modifyTime)
    f.close()


def _setFileModifyTime(aFile,modifyTime):
    """
        平台相关
       file aFile : writable opened file
       int modifyTime: file modify time
    """
    hfile=win32file._get_osfhandle(aFile.fileno( ))
    newTime=pywintypes.Time(modifyTime)
    win32file.SetFileTime(hfile,newTime,newTime,newTime)

def getFileSize( path ):
    return __getFileStatOf( path, stat.ST_SIZE )

def getFileData(path):
    dir,fileName=os.path.split(path)
    result=FileData()
    result.id=getHexdigest(path)
    result.name=fileName
    result.size=getFileSize(path)
    result.modifyTime=getFileModifyTime(path)
    return result

def __getFileStatOf( path, type ):
    """
    __getFileStatOf( str path, int type )
    
    type : stat.ST_SIZE,stat.ST_MTIME...
    """
    fileStats = os.stat ( path )
    return fileStats [ type ]

def getHexdigest(filePath):
    """ 
       getHexdigest(str filePath) -> str
    
       return  md5 hash 
    """
    f = open(filePath,'rb')
    import md5
    hsh = md5.new()
    while True:
        data = f.read(2048)
        if not data: break
        hsh.update(data)
    f.close()
    return hsh.hexdigest()

def splitPath(path):
    """
     把path='\a\b'的路径分离为['a','b']返回
    path: 必须是形如 \a\b 的绝对路径，也就是前面有\ 
    
    raise NotAbsolutePathError 非绝对路径的path参数将抛错"""
    result=[]
    def split(path):
        parent,name=os.path.split(path)
        if not name=='':
            result.insert(0,name)
            
        if path == parent:
            return
        
        split(parent)
    split(path)
    return result

def pickleDump(data,path):
    f=file(path,'w')
    cPickle.dump(data,f)
    f.close()
    
def pickleLoad(path):
    f=file(path,'r')
    try:
        result=cPickle.load(f)
    except Exception ,e:
        ee=Exception()
        
        raise Exception,"pickle版本不一致? ：" + str(e)
    
    f.close()
    return result

def xcopy(source,target,exceptPatterns):
    """
    str source: copy路径
    str target: 目标路径
    str exceptPatterns:可以使用文件名模式: "*" ,  "a*.bat"...
    """
    source=os.path.normpath(source)
    target=os.path.normpath(target)
    def walk(path):
        for exceptPattern in exceptPatterns:
            if fnmatch.fnmatch(path, exceptPattern):
                return 
        if os.path.isfile( path ):
            targetFile=path.replace(source,target,1)
            targetDir=os.path.split(targetFile)[0]
            if not os.path.exists(targetDir):
                os.makedirs(targetDir)
            #shutil.copy(path, targetDir) 
            import distutils.file_util
            distutils.file_util.copy_file(path,targetDir)
        elif os.path.isdir( path ):
            for childName in os.listdir( path ):
                fullpath = os.path.normpath(os.path.join(path,childName))
                walk(fullpath)
    walk(source)
